﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.IO;

namespace Ex12.VideoProcessing
{
    public class VideoProcessing
    {
        private const string CONNECTION_STRING = "Server=.\\SQLEXPRESS; Database=ATM; Integrated Security=true";

        public static void Main()
        {

            string inputFileName = "../../test-max.wmv";

            DateTime startDateTime = DateTime.Now;
            WriteVideo(inputFileName);
            DateTime endDateTime = DateTime.Now;
            TimeSpan duration = endDateTime - startDateTime;
            Console.WriteLine(string.Format("Hours{0} Minutes{1} Seconds {2}, Milliseconds{3}",
                duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds));
            //ReadVideo(18, "../../test-recreated.avi");
        }

        public static void ReadVideo(int videoID, string outputFileName)
        {
            try
            {
                using (SqlConnection dbCon = new SqlConnection(CONNECTION_STRING))
                {
                    using (SqlCommand cmdReadVideo = dbCon.CreateCommand())
                    {
                        dbCon.Open();
                        cmdReadVideo.CommandText = "SELECT VideoData FROM Videos WHERE VideoID = @videoID";
                        cmdReadVideo.Parameters.AddWithValue("@videoID", videoID);
                        using (FileStream fileWriter = new FileStream(outputFileName, FileMode.Create, FileAccess.Write))
                        {
                            using (SqlDataReader reader = cmdReadVideo.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    byte[] buffer = new byte[1024 * 1024];
                                    long bytesRead = 0;
                                    long dataIndex = 0;
                                    while ((bytesRead = reader.GetBytes(0, dataIndex, buffer, 0, buffer.Length)) > 0)
                                    {
                                        fileWriter.Write(buffer, 0, (int)bytesRead);
                                        dataIndex += bytesRead;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }

        public static void WriteVideo(string inputFileName)
        {
            try
            {
                using (SqlConnection dbCon = new SqlConnection(CONNECTION_STRING))
                {
                    using (SqlCommand cmdCreateVideo = dbCon.CreateCommand())
                    {
                        dbCon.Open();

                        using (FileStream fileReader = new FileStream(inputFileName, FileMode.Open, FileAccess.Read))
                        {
                            byte[] buffer = new byte[1024 * 1024];

                            int bytesRead = fileReader.Read(buffer, 0, buffer.Length);
                            cmdCreateVideo.CommandText = @"INSERT INTO Videos(VideoData) " +
                                        "VALUES (@setOfBits) ";
                            cmdCreateVideo.Parameters.AddWithValue("@setOfBits", buffer);    
                            cmdCreateVideo.ExecuteNonQuery();

                            SqlCommand cmdSelectIdentity =  new SqlCommand("SELECT @@Identity", dbCon);
                            int insertedVideoID = (int)(decimal)cmdSelectIdentity.ExecuteScalar();

                            while (true)
                                {
                                    bytesRead = fileReader.Read(buffer, 0, buffer.Length);
                                    if (bytesRead == 0)
                                    {
                                        break;
                                    }
                                    if (bytesRead < 1024 * 1024)
                                    {
                                        byte[] newBuff = new byte[bytesRead];
                                        cmdCreateVideo.Parameters.Clear();
                                        cmdCreateVideo.Parameters.AddWithValue("@setOfBits", newBuff);
                                    }
                                    cmdCreateVideo.CommandText = @"UPDATE Videos " +
                                        "SET VideoData = VideoData + @setOfBits " +
                                        "WHERE VideoID = @insertedVideoID ";
                                    //cmdCreateVideo.CommandText = "exec dbo.usp_WriteBuffer @setOfBits @insertedVideoID ";
                                    if (!cmdCreateVideo.Parameters.Contains("@insertedVideoID"))
                                    {
                                        cmdCreateVideo.Parameters.AddWithValue("@insertedVideoID", insertedVideoID);
                                    }
                                    cmdCreateVideo.ExecuteNonQuery();
                                }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                return;
            }
        }
    }
}
